package com.plata.base.aclr.common;

import com.plata.base.aclr.utils.LogTool;

import java.util.concurrent.FutureTask;

public abstract class SilentTask implements ITask<Void> {
    private static final String TAG = "SilentTask";

    protected volatile int mThreadPriority;
    protected volatile boolean mCanceled = false;
    protected int mStatus = Status.PENDING;
    protected String name;
    protected FutureTask task;

    public SilentTask(String name) {
        this.name = name;
        this.mThreadPriority = android.os.Process.THREAD_PRIORITY_BACKGROUND;
    }

    @Override
    public Void call() throws Exception {
        android.os.Process.setThreadPriority(this.mThreadPriority);
        setStatus(Status.RUNNING);
        if (!this.mCanceled) {
            try {
                this.runInBackground();
            } catch (Throwable e) {
                // for running safely
                LogTool.e(TAG, "run", e);
            }
        }
        setStatus(Status.FINISHED);
        return null;
    }

    @Override
    public void setFutureTask(FutureTask task) {
        this.task = task;
    }

    @Override
    public void setStatus(int status) {
        mStatus = status;
    }

    /**
     * Override this method to handle result from a worker thread.
     *
     * @return
     */
    public abstract void runInBackground() throws Exception;

    @Override
    public int getStatus() {
        return this.mStatus;
    }

    @Override
    public boolean isCanceled() {
        return this.mCanceled;
    }

    @Override
    public void cancel() {
        try {
            this.mCanceled = true;
            if (task != null) {
                task.cancel(true);
            }
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            task = null;
            setStatus(ITask.Status.FINISHED);
        }
    }

    @Override
    public void setThreadPriority(int priority) {
        this.mThreadPriority = priority;
    }

    @Override
    public String getName() {
        return name;
    }
}
